package org.apache.sad.core.framework.jaxrpc;

import java.lang.reflect.Method;

import javax.xml.rpc.Service;
import javax.xml.rpc.Stub;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.apache.sad.core.framework.exception.SystemException;

/**
 *
 * @author Anup Dixit
 *
 */
public abstract class JaxRpcRuntimeBase implements JaxRpcRuntime, InitializingBean {
	
	protected static final String GET = "get";
	
	protected final static Log log = LogFactory.getLog(JaxRpcRuntimeBase.class);

	protected Class serviceClass;

    /**
     * Sets the service class.
     *
     * @param serviceClass the service class.
     */
    public void setServiceClass(Class serviceClass) {
        this.serviceClass = serviceClass;
    }

	public Class getServiceClass() {
		return serviceClass;
	}	

	public void afterPropertiesSet() throws Exception {
        if (serviceClass == null) {
            throw new SystemException("Property of serviceClass is missing.");
        }		
	}
	  
	public Service createJaxRpcService() throws SystemException {		
        try {
        	//can not be cached - threadsafe issue
			return (Service) serviceClass.newInstance();
		} catch (InstantiationException e) {
			throw new SystemException("Failed to create JaxRpc service.", e);
		} catch (IllegalAccessException e) {
			throw new SystemException("Failed to create JaxRpc service.", e);
		}
	}	
	
	public Stub getPort(Service jaxRpcService, String portName) throws SystemException {
        try {
            Method method = jaxRpcService.getClass().getMethod(getMethodName(portName), new Class[0]);
            return (Stub) method.invoke(jaxRpcService, new Object[0]);
        } catch (Exception e) {
        	throw new SystemException("Failed to get JaxRpc port.", e);
        }
	}
	
	protected abstract String getMethodName(String portName);
}
